#!/usr/bin/env python
# -*-coding:UTF-8-*-
# Author: chenzuoqing@126.com
# Create: 2018/8/15 15:26
# File  : mixins.py

"""
inception动作类封装
"""

import re
from utils.tasks import send_mail
from utils.pass_crypt import PasswordCrypt
from utils.inception import Inception
from sqlaudit.models import DatabaseConfig


class ActionMxins(object):
    action_desc_map = {
        'execute': '代执行',
        'reject': '代放弃',
        'rollback': '代回滚'
    }
    connect_error = 'MySQL连接异常 '
    forbidden_words = '禁用关键字 '
    exception_sqls = 'SQL语法错误 '
    not_exists_group = '用户的组不存在 '
    executed = 'SQL已执行过'

    @staticmethod
    def get_db_addr(user, password, host, port, actiontype):
        pc = PasswordCrypt()
        password = pc.decrypt(password)
        db_addr = '--user={}; --password={}; --host={}; --port={}; {};'.format(user, password, host, port, actiontype)
        return db_addr

    def mail(self, sql_obj, mail_type):
        # 线上环境，发邮件提醒
        if sql_obj.env == 'prod':
            username = self.request.user.username
            treater_mail = sql_obj.treater.email
            commiter_mail = sql_obj.commiter.email
            mailto_list = [commiter_mail, treater_mail]
            mailto_list = list(set(mailto_list))  # 去重
            # 发送邮件
            return send_mail(mailto_list, username, sql_obj.id, sql_obj.remark, mail_type,
                             sql_obj.sql_content, sql_obj.database.name)

    def replace_remark(self, sql_obj):
        username = self.request.user.username
        uri = self.request.META['PATH_INFO'].split('/')[-2]
        # 如果是超级权限或管理代执行的
        if username != sql_obj.treater.username:
            sql_obj.remark += '   [' + username + self.action_desc_map.get(uri) + ']'
        sql_obj.save()

    def check_execute_sql(self, db_id, sql_content):
        dbobj = DatabaseConfig.objects.get(id=db_id)

        # 根据数据库名 匹配其地址信息，"--enable-check" 只审核
        db_addr = self.get_db_addr(dbobj.user, dbobj.password, dbobj.host, dbobj.port, self.action_type)

        # 审核
        sql_review = Inception(sql_content, dbobj.name).inception_handle(db_addr)
        result, status = sql_review.get('result'), sql_review.get('status')

        # 判断检测错误，有则返回
        if status == -1 or len(result) == 1:  # 兼容2种版本的抛错
            return [], result

        success_sqls = []
        exception_sqls = []
        for sql_result in result:
            error_message = sql_result[4]
            if error_message == 'None' or re.findall('Warning', error_message):
                success_sqls.append(sql_result)
            else:
                exception_sqls.append(error_message)

        return success_sqls, exception_sqls
